/***************************** BEGIN LICENSE BLOCK ***************************

 The contents of this file are subject to the Mozilla Public License Version
 1.1 (the "License"); you may not use this file except in compliance with
 the License. You may obtain a copy of the License at
 http://www.mozilla.org/MPL/MPL-1.1.html
 
 Software distributed under the License is distributed on an "AS IS" basis,
 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the License.
 
 The Original Code is "SensorHub".
 
 The Initial Developer of the Original Code is Sensia Software LLC.
 <http://www.sensiasoftware.com>. Portions created by the Initial
 Developer are Copyright (C) 2013 the Initial Developer. All Rights Reserved.
 
 Please Contact Alexandre Robin <alex.robin@sensiasoftware.com> for more 
 information.
 
 Contributor(s): 
    Alexandre Robin <alex.robin@sensiasoftware.com>
 
******************************* END LICENSE BLOCK ***************************/

package org.sensorhub.impl.sensor;

import org.sensorhub.api.common.Event;
import org.sensorhub.api.common.IEventListener;
import org.sensorhub.api.common.SensorHubException;
import org.sensorhub.api.module.IModule;
import org.sensorhub.api.module.IModuleStateLoader;
import org.sensorhub.api.module.IModuleStateSaver;
import org.sensorhub.api.persistence.DataKey;
import org.sensorhub.api.persistence.IBasicStorage;
import org.sensorhub.api.persistence.StorageException;
import org.sensorhub.api.sensor.ISensorDataInterface;
import org.sensorhub.api.sensor.ISensorModule;
import org.sensorhub.api.sensor.SensorDataEvent;
import org.sensorhub.api.sensor.SensorException;
import org.sensorhub.api.sensor.SensorStorageConfig;
import org.sensorhub.impl.SensorHub;
import org.sensorhub.impl.common.BasicEventHandler;
import org.sensorhub.impl.module.ModuleRegistry;
import org.vast.cdm.common.DataBlock;


/**
 * <p>
 * This class is a simple event-based process that saves data generated by a
 * sensor in the specified storage.
 * </p>
 *
 * <p>Copyright (c) 2013</p>
 * @author Alexandre Robin <alex.robin@sensiasoftware.com>
 * @since Oct 5, 2013
 */
public class SensorStorageHelper implements IModule<SensorStorageConfig>, IEventListener
{
    SensorStorageConfig config;
    IBasicStorage<?> storage;
    ISensorModule<?> sensor;
    BasicEventHandler eventHandler;


    public SensorStorageHelper()
    {
        eventHandler = new BasicEventHandler();
    }
    
    
    @Override
    public boolean isEnabled()
    {
        return config.enabled;
    }


    @Override
    public void init(SensorStorageConfig config) throws SensorHubException
    {
        this.config = config;
    }


    @Override
    public void updateConfig(SensorStorageConfig config) throws SensorHubException
    {      
        // TODO Auto-generated method stub
    }

    
    @Override
    public void start() throws SensorHubException
    {
        // get handle to storage and sensor
        ModuleRegistry moduleReg = SensorHub.getInstance().getModuleRegistry();
        storage = (IBasicStorage<?>)moduleReg.getModuleById(config.storageID);
        sensor = (ISensorModule<?>)moduleReg.getModuleById(config.sensorID);
        
        // register to sensor events
        if (config.selectedOutputs == null || config.selectedOutputs.length == 0)
        {
            for (ISensorDataInterface output: sensor.getAllOutputs().values())
                output.registerListener(this);
        }
        else
        {
            for (String outputName: config.selectedOutputs)
                sensor.getAllOutputs().get(outputName).registerListener(this);
        }
    }
    
    
    @Override
    public void stop() throws StorageException
    {
        try
        {
            for (String outputName: config.selectedOutputs)
                sensor.getAllOutputs().get(outputName).unregisterListener(this);
        }
        catch (SensorException e)
        {
        }
    }
    
    
    @Override
    public SensorStorageConfig getConfiguration()
    {
        return config;
    }


    @Override
    public String getName()
    {
        return config.name;
    }


    @Override
    public String getLocalID()
    {
        return config.id;
    }


    @Override
    public void cleanup() throws StorageException
    {
        sensor = null;
    }
    
    
    @Override
    public void handleEvent(Event e)
    {
        if (e instanceof SensorDataEvent)
        {
            boolean saveAutoCommitState = storage.isAutoCommit();
            storage.setAutoCommit(false);
            
            String producer = ((SensorDataEvent) e).getSensorId();
            
            for (DataBlock record: ((SensorDataEvent) e).getRecords())
            {
                DataKey key = new DataKey(producer, e.getTimeStamp());
                storage.store(key, record);
                System.out.println("Storing record " + key.timeStamp + " in DB");
                System.out.println("DB size: " + storage.getNumRecords());
            }
            
            storage.commit();
            storage.setAutoCommit(saveAutoCommitState);
        }        
    }
    

    @Override
    public void saveState(IModuleStateSaver saver) throws SensorHubException
    {
        // TODO Auto-generated method stub
    }


    @Override
    public void loadState(IModuleStateLoader loader) throws SensorHubException
    {
        // TODO Auto-generated method stub
    }

}
